﻿package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.*;
	import mkv.data.FFONSerializer;
	import mkv.data.Microformat;
	
	/**
	 * Test harness for FFON
	 * @author John Beech
	 */
	public class main extends Sprite 
	{		
		/* UI Elements */
		public var debugbox:TextField;
		
		/* Test objects */
		public var MicroformatLoader:FFONSerializer;
		public var ffon1:FFONSerializer;
		public var ffon2:FFONSerializer;
		public var ffon3:FFONSerializer;
		public var ffon4:FFONSerializer;
		public var microformats:Array;
		
		public var tasks:Array;
		public var currentTask:Function;
		
		public function main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			Setup();
		}
		
		public function Setup():void
		{
			CreateChildren();
			AttachEvents();
			
			RunTests();
		}
		
		public function CreateChildren():void
		{
			debugbox = CreateTextField(10, 10, 12, 700, 600);
			
			addChild(debugbox);
		}
		
		public function AttachEvents():void
		{
			
		}
		
		public function RunTests():void
		{
			debugbox.text = "";
			LocalTrace("[Starting Tests]");
			
			tasks = [];
			tasks.push(RunTest1_PartA);
			tasks.push(RunTest1_PartB);
			tasks.push(RunTest2);
			tasks.push(RunTest3);
			tasks.push(RunTest4);
			
			ProcessTasks();
		}
		
		public function ProcessTasks():void {
			if(tasks.length > 0) {
				if (currentTask == null) {
					currentTask = tasks[0];
					tasks.splice(0, 1);
					currentTask();
				}
			}
			else {
				LocalTrace("");
				LocalTrace("[All Tasks Complete]");
			}
		}
		
		public function CompleteTask(task:Function):void {
			if (task != currentTask) {
				LocalTrace("Tried to complete a task out of sequence");
				throw new Error("Tried to complete a task out of sequence");
			}
			currentTask = null;
			ProcessTasks();
		}
		
		public function RunTest1_PartA():void {
			MicroformatLoader = new FFONSerializer();
			MicroformatLoader.Load("microformats.ffon", FFONMicroformatsSuccess, FFONError);
		}
		
		public function RunTest1_PartB():void {
			ffon1 = new FFONSerializer();
			for each(var mf:Microformat in microformats) {
				ffon1.AddMicroformat(mf);
			}
			ffon1.Load("test-basic.ffon", FFONSuccess1, FFONError);
		}
		
		public function RunTest2():void {
			ffon2 = new FFONSerializer();
			ffon2.Load("non_existant_file.ffon", FFONSuccess2, FFONError);
		}
		
		public function RunTest3():void {
			ffon3 = new FFONSerializer();
			ffon3.parseMicroformats = true;
			
			ffon3.Load("test-embedded-microformats.ffon", FFONSuccess3, FFONError);
		}
		
		public function RunTest4():void {
			ffon4 = new FFONSerializer();
			ffon4.parseMicroformats = true;
			
			ffon4.Load("test-nested-paths.ffon", FFONSuccess4, FFONError);
		}
		
		public function FFONMicroformatsSuccess(ffon:FFONSerializer):void {			
			microformats = [];
			var mf:Microformat;
			
			if (ffon.data.hasOwnProperty("Microformats")) {
				var value:String;
				LocalTrace("\nTest 1 Results Part A - Microformats: ");
				for (var key:String in ffon.data.Microformats) {
					value = ffon.data.Microformats[key];
					
					LocalTrace(" " + key + ": " + value);
					
					mf = new Microformat(value, key);
					microformats.push(mf);
				}
			}
			else {
				LocalTrace("No valid microformats were found to process");
				throw new Error("No valid microformats were found to process");
			}
			
			CompleteTask(RunTest1_PartA);
		}
		
		public function FFONSuccess1(ffon:FFONSerializer):void {
			LocalTrace("FFON File: " + ffon.filepath + " loaded OK");
			
			LocalTrace("\nTest 1 Result Part B - Data access:");
			LocalTrace("Config.path: " + ffon.data.Config.path);
			LocalTrace("Building.property[0].name: " + ffon.data.Building.property[0].name)
			LocalTrace("Building.property[0].description: " + ffon.data.Building.property[0].description);
			LocalTrace("Graphic[0].id: " + ffon.data.Graphic[0].id)
			LocalTrace("Graphic[1].id: " + ffon.data.Graphic[1].id);
			
			CompleteTask(RunTest1_PartB);
		}
		
		public function FFONSuccess2(ffon:FFONSerializer):void {
			LocalTrace("Non existant file load ERROR:")
			LocalTrace("FFON File: " + ffon.filepath + " loaded OK");
			
			throw new Error("Did not expect to load " + ffon2.filepath + "! This test has failed.");
		}
		
		public function FFONError(ffon:FFONSerializer):void {
			if (ffon == ffon2) {
				LocalTrace("\nTest 2 Result - Expecting error:");
					
				CompleteTask(RunTest2);
			}
			else {
				LocalTrace("FFON File: " + ffon.filepath + " failed to load");
			}
		}
		
		public function FFONSuccess3(ffon:FFONSerializer):void {
			LocalTrace("FFON File: " + ffon.filepath + " loaded OK");
			
			LocalTrace("\nTest 3 Results (auto-parsed microformats):");
			LocalTrace("Tests.image_html.alt: " + ffon.data.Tests.image_html.alt);
			LocalTrace("Tests.image_html.src: " + ffon.data.Tests.image_html.src);
			LocalTrace("Tests.image_html.width: " + ffon.data.Tests.image_html.width);
			LocalTrace("Tests.image_html.height: " + ffon.data.Tests.image_html.height);
			
			CompleteTask(RunTest3);
		}
		
		public function FFONSuccess4(ffon:FFONSerializer):void {
			LocalTrace("FFON File: " + ffon.filepath + " loaded OK");
			
			var data:Object = ffon.data;
			
			LocalTrace("\nTest 4 Results (nested paths):");
			LocalTrace("Config[].length: " + data.Config.length);
			LocalTrace("Other.extending.the[].length: " + data.Other.extending.the.length);
			LocalTrace("Other.extending.the[0].possibilities.of.code: " + data.Other.extending.the[0].possibilities.of.code);
			
			CompleteTask(RunTest4);
		}
		
		public function LocalTrace(text:String):void {
			debugbox.appendText(text);
			debugbox.appendText("\n");
			
			trace(text);
		}
		
		public static function CreateTextField(xPos:int=0, yPos:int=0, fontSize:int=10, width:int=150, height:int=25):TextField {
            var tf:TextField = new TextField();
            tf.textColor = 0xFFFFFF;
            tf.text = "hello";
            tf.selectable = true;
            tf.autoSize = TextFieldAutoSize.NONE;
			tf.antiAliasType = AntiAliasType.ADVANCED;
			tf.wordWrap = true;
			tf.width = width;
			tf.height = height;
            tf.x = xPos;
            tf.y = yPos;
			
			var style:TextFormat = new TextFormat();
			style.bold = true;
			style.size = fontSize;
			style.font = "Verdana";
			tf.setTextFormat(style);
			tf.defaultTextFormat = style;
			
			return tf;
        }
		
	}
	
}